package com.xiaochong.tir.trades.component;

import com.alibaba.fastjson.JSON;
import com.xc.logclient.utils.LogTrace;
import com.xiaochong.tir.common.data.hbasepo.TradesToKLine;
import com.xiaochong.tir.common.util.DateUtils;
import com.xiaochong.tir.common.util.HbaseTableUtils;
import com.xiaochong.tir.trades.component.hbase.CurrencyInfoHbaseComponent;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.MathContext;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

/**
 * @Description: 处理k线数据
 * @Author: org
 * @CreateDate: 2018/9/3 18:06
 */
@Component
public class KActionSaveHbaseCommon {
    @Autowired
    private HbaseBaseQueryComponent hbaseBaseQueryComponent;
    @Autowired
    private CurrencyInfoHbaseComponent currencyInfoHbaseComponent;
    public void MqDataSaveTradesAction(String body) {
        LogTrace.beginTrace("接受一分钟k线，计算其他段落k线数据start");
        if(StringUtils.isBlank(body)){
            return;
        }
        TradesToKLine kLine = JSON.parseObject(body,TradesToKLine.class);
        if(kLine == null){
            return;
        }
        long dateTime = Long.valueOf(kLine.getTimestamp());
        LocalDateTime localDateTime = DateUtils.getDateTimeOfTimestamp(dateTime);
        //当前5分钟
        makeFiveMinusKAction(localDateTime,kLine,HbaseTableUtils.K_ACTION_K_LINE_ROW_KEY_5M,5,1,DateUtils.format_ymdhm);
        //当前15分钟
        makeFiveMinusKAction(localDateTime,kLine,HbaseTableUtils.K_ACTION_K_LINE_ROW_KEY_15M,15,1,DateUtils.format_ymdhm);
        //当前30分钟
        makeFiveMinusKAction(localDateTime,kLine,HbaseTableUtils.K_ACTION_K_LINE_ROW_KEY_30M,30,1,DateUtils.format_ymdhm);
        //当前一小时
        makeFiveMinusKAction(localDateTime,kLine,HbaseTableUtils.K_ACTION_K_LINE_ROW_KEY_1H,60,1,DateUtils.format_ymdh);
        //当前4小时
        makeFiveMinusKAction(localDateTime,kLine,HbaseTableUtils.K_ACTION_K_LINE_ROW_KEY_4H,4,2,DateUtils.format_ymdh);
        //当前日
        makeFiveMinusKAction(localDateTime,kLine,HbaseTableUtils.K_ACTION_K_LINE_ROW_KEY_1D,0,3,DateUtils.format_ymds);
        //当前周
        makeFiveMinusKAction(localDateTime,kLine,HbaseTableUtils.K_ACTION_K_LINE_ROW_KEY_1W,0,4,DateUtils.format_ymds);
        //当前月
        makeFiveMinusKAction(localDateTime,kLine,HbaseTableUtils.K_ACTION_K_LINE_ROW_KEY_1Mo,0,5,DateUtils.format_ymds);
    }

    /**
     *
     * @param dateTime 时间
     * @param kLine 接收到数据
     * @param head hbase中rowkey的头部
     * @param m  分钟段落已使用，其他无用，15M传15,30M传30
     * @param type 1：分钟，2，时间
     * @param format 格式
     */
    private void makeFiveMinusKAction(LocalDateTime dateTime, TradesToKLine kLine,String head,int m,Integer type,DateTimeFormatter format) {
        try {
            LocalDateTime local = dateTime.minusMinutes(0);
            //获取当前段落
            if(type == 1){//获取当前时间段的分钟值
                int yu = local.getMinute()%m;
                local = local.minusMinutes(yu);
            }else if(type == 2){//时
                int yu = local.getHour()%m;
                local = local.minusHours(yu);
            }else if(type == 3){//获取当前时间段的日
                local = local.minusMinutes(0);
            }else if(type == 4){//获取当前时间段的周
                while (local.getDayOfWeek() != DayOfWeek.SUNDAY){
                    local = local.minusDays(1);
                }
            }else if(type == 5){//获取当前时间段的月
                int yu = local.getDayOfMonth() - 1;
                local = local.minusDays(yu);
            }

            String transactionName = kLine.getPair();
            Integer exchangeId = kLine.getExchangeId();
            //获取当前段的k线值
            String rowKeyOld = head+"@"+exchangeId + "@" + transactionName + "@" + DateUtils.localDateTimeFormatString(local, format);
            TradesToKLine tradesToKLine = getHbaseDataByRowKey(rowKeyOld);
            if(tradesToKLine != null){ //判断时候存在，不存在直接插入，否则求出最高，最低值，交易量，并且插入收盘值
                BigDecimal volume = new BigDecimal(tradesToKLine.getVolume()).add(new BigDecimal(kLine.getVolume()));
                tradesToKLine.setVolume(volume.stripTrailingZeros().toPlainString());
                tradesToKLine.setClosePrice(kLine.getClosePrice());
                //最高价格
                if (StringUtils.isBlank(tradesToKLine.getHighestPrice())) {
                    tradesToKLine.setHighestPrice(kLine.getHighestPrice());
                } else {
                    BigDecimal bigDecimal = new BigDecimal(kLine.getHighestPrice());
                    BigDecimal highOpen = new BigDecimal(tradesToKLine.getHighestPrice());
                    if (bigDecimal.compareTo(highOpen) > 0) {
                        tradesToKLine.setHighestPrice(kLine.getHighestPrice());
                    }
                }
                //最低价格
                if (StringUtils.isBlank(tradesToKLine.getLowestPrice())) {
                    tradesToKLine.setLowestPrice(kLine.getLowestPrice());
                } else {
                    BigDecimal bigDecimal = new BigDecimal(kLine.getLowestPrice());
                    BigDecimal lowClose = new BigDecimal(tradesToKLine.getLowestPrice());
                    if (bigDecimal.compareTo(lowClose) < 0) {
                        tradesToKLine.setLowestPrice(kLine.getLowestPrice());
                    }
                }
            }else{
                tradesToKLine = new TradesToKLine();
                tradesToKLine.setTimestamp(String.valueOf(DateUtils.localDateTimeToDate(local).getTime()));
                tradesToKLine.setOpenPrice(kLine.getOpenPrice());
                tradesToKLine.setHighestPrice(kLine.getHighestPrice());
                tradesToKLine.setLowestPrice(kLine.getLowestPrice());
                tradesToKLine.setClosePrice(kLine.getClosePrice());
                tradesToKLine.setVolume(kLine.getVolume());
            }

            //如果不存在直接插入，否则判断当前数据与老数据的最高最低价格以及收盘价格
            if(StringUtils.isNotBlank(tradesToKLine.getOpenPrice())){
                currencyInfoHbaseComponent.insertHbaseObject(HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_NAME ,rowKeyOld, HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_FAMILY , tradesToKLine);
            }

        }catch (Exception e){
            e.printStackTrace();
            LogTrace.error("接受一分钟k线，计算其他段落k线数据-Error",e);
        }

    }
    /**
     * 根据row获取数据5,15等
     * @param rowKey
     * @return
     * @throws Exception
     */
    public TradesToKLine getHbaseDataByRowKey(String rowKey) throws Exception{
        Map<String, Object> hbaseData = hbaseBaseQueryComponent.selectData(HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_NAME
                , rowKey);
        if(null != hbaseData && hbaseData.get("volume") != null && hbaseData.get("openPrice") != null && hbaseData.get("highestPrice") != null&& hbaseData.get("lowestPrice") != null&& hbaseData.get("closePrice") != null){
            TradesToKLine tradesToKLine = new TradesToKLine();
            tradesToKLine.setTimestamp(hbaseData.get("timestamp").toString());
            tradesToKLine.setVolume(hbaseData.get("volume").toString());
            tradesToKLine.setOpenPrice(hbaseData.get("openPrice").toString());
            tradesToKLine.setClosePrice(hbaseData.get("closePrice").toString());
            tradesToKLine.setHighestPrice(hbaseData.get("highestPrice").toString());
            tradesToKLine.setLowestPrice(hbaseData.get("lowestPrice").toString());
            return tradesToKLine;
        }
        return null;
    }

    /**
     * 防止失去精度
     * @param lastPriceB
     * @return
     */
    public static String getConverCut(String lastPriceB) {
        BigDecimal result = BigDecimal.ZERO;
        result = StringUtils.isNotBlank(lastPriceB)?new BigDecimal(lastPriceB).setScale(12,BigDecimal.ROUND_DOWN):BigDecimal.ZERO;
        /*if(result.compareTo(BigDecimal.valueOf(1)) >=0){
            result = result.setScale(2,BigDecimal.ROUND_DOWN);
        }else{
            BigDecimal divisor = BigDecimal.ONE;
            MathContext mc = new MathContext(5);
            result = result.divide(divisor, mc);
        }*/
        return result.stripTrailingZeros().toPlainString();
    }
}
